<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<style type="text/css">
		@import "../../dojo/resources/dojo.css";
		@import "../../dojox/grid/resources/Grid.css";
		@import "../../dojox/grid/resources/soriaGrid.css";

		html, body, #main{	
			width: 100%;	/* make the body expand to fill the visible window */
			height: 100%;
			overflow: hidden;	/* erase window level scrollbars */
			padding: 0 0 0 0;
			margin: 0 0 0 0;
			font: 10pt Arial,Myriad,Tahoma,Verdana,sans-serif;
		}
		
		#checks label {
			padding: 4px;
			float: left;
		}
		#checks input {
			float: right;
		}
		#checks div {
			height: 15px;
			padding: 4px;
			margin-top: 5px;
		}
	</style>

	<!-- required: the default dijit theme: -->
	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/soria/soria.css">

	<!-- required: dojo.js -->
	<script type="text/javascript" src="../../dojo/dojo.js"
		djConfig="isDebug: true, parseOnLoad: true"></script>

	<script type="text/javascript">
		dojo.require("dijit.dijit"); // optimize: load dijit layer
		dojo.require("dijit.layout.BorderContainer");
		dojo.require("dijit.form.FilteringSelect");
		dojo.require("dijit.form.Button");
		dojo.require("dijit.layout.TabContainer");
		dojo.require("dijit.layout.ContentPane");
		dojo.require("dojox.grid.DataGrid");
		dojo.require("dojo.data.ItemFileReadStore");
		dojo.require("dojo.date.locale");
		dojo.require("dijit.Dialog");
	</script>

	
	<script type="text/javascript" src="checkstyleUtil.js"></script>
	<script type="text/javascript">
		var singleFileStore;
		var errorQuery;
		var saveErrorMsg = "You may need to rename the checkstyle.php.rename.html file to checkstyle.php."
								+ "\nPlease read the readme.txt file in the /util/checkstyle folder.";

		dojo.addOnLoad(function(){
			checkstyleStore.fetch({query: {date : '*'}, onComplete: function(items){
				var checkstyleReportDate = new Date(checkstyleStore.getValue(items[0], "date"));
				var dateStr = dojo.date.locale.format((new Date(checkstyleReportDate)), {formatLength: "medium"});
					
				document.title = "Dojo Checkstyle report generated on " + dateStr;
				dojo.byId("reportDate").innerHTML = dateStr;	
			}});
			
			dojo.connect(dijit.byId("messagesGrid"), "onRowClick", doEdit);
			
		});
		var cachedFiles = {};
		var changedFiles = [];
		var navKeys = {};
		dojo.forEach([dojo.keys.UP_ARROW, dojo.keys.DOWN_ARROW, 
						dojo.keys.LEFT_ARROW, dojo.keys.RIGHT_ARROW, 
						dojo.keys.ENTER], function(code){
							navKeys[code] = true;
						});
		function updateLine(evt) {
			evt = dojo.fixEvent(evt);
			if (navKeys[evt.keyCode]) {
				dojo.byId("lineNumber").innerHTML = getCursorPosition(evt.target);
			}
		}
		
		function getCursorPosition(textarea) {
			if(textarea.selectionStart){
				return textarea.selectionStart;
			}else if(dojo.doc.selection){ //IE
				var range = dojo.doc.selection.createRange();
				return range;
			}
		}

		function onFolderClick(evt) {
			var folderName = evt.grid.store.getValue(
								evt.grid.getItem(evt.rowIndex), "file");
			if (dojo.trim(folderName) == "All") {
				folderName = "";
			} else if (folderName.charAt(folderName.length - 1) != "/"){
				folderName += "/";
			}

			showAllErrors({file: folderName + "*", folder: 0});
			dijit.byId("mainTab").selectChild(dijit.byId("errorsTab"));
		}
		var chartInitialized = false;

		dojo.subscribe("mainTab-selectChild", function(tab){
			if(chartInitialized || tab.id != "chartTab"){
				return;
			}
			chartInitialized = true;
			checkstyleStore.fetch({query: {file: "*"}, onComplete: initializeChart});
		});
		function initializeChart(items) {
			
			dojo.require("dojox.charting.DataChart");
			dojo.require("dojox.charting.action2d.Highlight");
			dojo.require("dojox.charting.action2d.Tooltip");
			dojo.require("dojox.charting.plot2d.Columns");
			
			var folderCounts = {};
						
			dojo.forEach(items, function(item){
			  var fileName = checkstyleStore.getValue(item, "file");
			  
			  var parts = fileName.split("/");
			  if (parts.length < 2) {
			  	return;
			  }
			  var folderName = parts[0] + "/" + parts[1];
			  
			  if (!folderCounts[folderName]) {
			  	folderCounts[folderName] = 0;
			  }
			  folderCounts[folderName]++;
			});
			
			var folderCountsArr = [];

			for (var x in folderCounts) {
			  folderCountsArr.push({"folder": x, count: folderCounts[x]});
			}
			folderCountsArr.sort(function(a, b){
			  if(a.count < b.count) {
			  	return 1;
			  } else if(a.count > b.count){
			  	return -1;
			  }
			  return 0;
			});

			if (folderCountsArr.length > 20) {
				folderCountsArr = folderCountsArr.slice(0, 20);
			}
			dojo.forEach(folderCountsArr, function(item, index){
				item.id = index + 1;
			});
			var chartStore = new dojo.data.ItemFileReadStore({
				data: {
					identifier: 'id',
					label: 'folder',
					items: folderCountsArr
				}
			});
			var chart = new dojox.charting.DataChart("chart", {
				displayRange:12,
				yaxis:{
					max: folderCountsArr[0].count + 10, 
					min: Math.max(0, folderCountsArr[folderCountsArr.length -1].count - 10), 
					majorTickStep: Math.round(folderCountsArr[0].count / 10), 
					maxLabelSize:20,
					labelFunc: function(val) {
						return val;
					}
				},
				xaxis: {
					labelFunc: "seriesLabels",
					maxLabelSize:30
				},
				scroll:false,
				type: dojox.charting.plot2d.Columns
			});
			
			
			var dc = dojox.charting;
			new dc.action2d.Highlight(chart, "default");
			new dc.action2d.Tooltip(chart, "default");
			
			chart.setStore(chartStore, {folder: "*"}, "count");	
		}
		
		function formatMessage(item) {
			return (singleFileStore || checkstyleStore).getValue(item, "msg");
		}
		
		function doEdit(item) {
			var grid = dijit.byId("messagesGrid");
			var textarea = dojo.byId("editInput");
			
			var q = {folder: 0};
			
			if (errorQuery) {
				q.file = errorQuery.file;
			}
			
			grid.store.fetch({
				query: q,
				start: item.rowIndex,
				count: 1,
				onComplete: function(items) {
					var file = grid.store.getValue(items[0], "file");
					var line = grid.store.getValue(items[0], "line");

					if (textarea._file != file) {
						if (textarea._file) {
							if(cachedFiles[textarea._file] && cachedFiles[textarea._file] != textarea.value) {
								changedFiles.push(textarea._file);
							}
							cachedFiles[textarea._file] = textarea.value;
						}
						textarea._file = file;
						if (cachedFiles[file]) {
							textarea.value = cachedFiles[file];
						}
						else {
							loadFile(file, line);
						}
					} else {
						gotoLine(line);
					}
				}
			});
		}
		
		function loadFile(file, line) {
			var textarea = dojo.byId("editInput");
			textarea.value = "Loading....";
			dojo.xhrGet({
				url: "../../" + file,
				type: "text",
				load: function(text)  {
					textarea.value = text;
					dijit.byId("showFileErrorsBtn").attr("disabled", false);
					gotoLine(line);
				}
			});
		}
		
		function gotoLine(line) {
			var count = line;
			var textarea = dojo.byId("editInput");
			var str = textarea.value;
			var i;
			for (i = 0; i < str.length && count > 1; i++) {
				if (str.charAt(i) == "\n") {
					count--;
				}
			}
			var nextNL = str.indexOf("\n", i + 1);
			selectChars(textarea, i, nextNL < 0 ? str.length - 1 : nextNL);
		}
		
		function selectChars(textarea, start, end) {
			
			if(textarea.setSelectionRange){
				setTimeout(function(){
				//	textarea.focus();
					textarea.setSelectionRange(start, start + 1);	
					var ev = document.createEvent("KeyEvents");
					ev.initKeyEvent("keypress", true, true, window, false, false, false, false, 0,
						textarea.value.charCodeAt(start));
					textarea.dispatchEvent(ev);
					textarea.setSelectionRange(start, end);	
					textarea.focus();
				}, 10);
				
			}else if(dojo.doc.selection){ //IE
				
				var range = dojo.doc.selection.createRange();
				// delete overflow characters
				range.moveStart("character", start);
				range.text = '';
				// show cursor
				range.select();
			}
		}
		
		function showCurrentErrors(){
			dijit.byId("showAllErrorsBtn").attr("checked", false);
			dijit.byId("showFileErrorsBtn").attr("checked", true);
			
			var textarea = dojo.byId("editInput");
			var value = textarea.value;
			checkstyleUtil.clear();

			checkstyleUtil.applyRules(textarea._file, value);
			var report = checkstyleUtil.generateReport(true);
			var storeData = dojo.eval("(" + report + ")");
			
			singleFileStore = new dojo.data.ItemFileReadStore({
				data: storeData
			});

			var grid = dijit.byId("messagesGrid");
			errorQuery = null;
			grid.setStore(singleFileStore, {folder: 0}, grid.attr("queryOptions"));
		}

		function showAllErrors(query){
			errorQuery = query;
		
			dijit.byId("showFileErrorsBtn").attr("checked", false);
			dijit.byId("showAllErrorsBtn").attr("checked", true);
			var grid = dijit.byId("messagesGrid");
			singleFileStore = null;
			grid.setStore(checkstyleStore, query || grid.attr("query"), grid.attr("queryOptions"));
		}
		
		function makeSimpleFixes() {
			var textarea = dojo.byId("editInput");
		
			textarea.value = checkstyleUtil.makeSimpleFixes(textarea.value);
			
			if(dojo.indexOf(changedFiles, textarea._file) < 0) {
				changedFiles.push(textarea._file);
			}
			showCurrentErrors();
		}
		
		function saveFile(fileName, contents, callback) {
			var textarea = dojo.byId("editInput");
			fileName = fileName || textarea._file;
			contents = contents || textarea.value;
			
			dojo.xhrPost({
				url: "checkstyle.php",
				content: {
					action: "save",
					filename: fileName,
					contents: contents
				}, 
				handle: function(text, reqObj){
					if (reqObj.xhr.readyState != 4) {
						return;
					}
					if (reqObj.xhr.status == 200) {
						if (!callback) {
							alert("File " + fileName + " saved");
						} else {
							callback(true);
						}
						var idx = dojo.indexOf(changedFiles, fileName);
						array.splice(idx, 1);
					}
					else if (callback){
						callback(false);
					} else {
						alert("Failed to save file " + fileName + ". " + saveErrorMsg);
					}
				}
			});
		}
		
		function showSaveDialog(){
			if (changedFiles.length == 0) {
				alert("No files have been altered yet.");
				return;
			}
			
			var checksNode = dojo.byId("checks");
			dojo.empty(checksNode);
			
			dojo.forEach(changedFiles, function(fileName){
				dojo.create("div", {
					innerHTML: "<label for='" + fileName + "'>" + fileName + "</label>"
						+ "<input type='checkbox' id='" + fileName + "'></input>"
				}, checksNode);
			});
			dijit.byId("changedFilesDlg").show();
		}
		
		function saveAllChangedFiles(){
			var successes = 0;
			var inputs = dojo.query("input", "checks").forEach(
				function(input) {
					if (!input.checked) {
						return;
					}
					var fileName = dojo.attr(input, "id");
					saveFile(fileName, cachedFiles[fileName], function(success){
						if (!success) {
							alert("Failed to save " + fileName
								+ saveErrorMsg);
						} else {
							successes++;
							if (successes = inputs.length) {
								alert("All files saved successfully");
								dijit.byId("changedFilesDlg").hide();
							}
						}
					});
				}
			);
		}
		
		var checkstyleStore;
		
		dojo.xhrGet({
			url: "checkstyleData.js",
			sync: true,
			handleAs: "json",
			load: function(data) {
				checkstyleStore = new dojo.data.ItemFileReadStore({
					data: data
				});
			},
			error: function(){
				alert("Error: could not load the checkstyle data. You should run the checkstyle tool in util/checkstyle/");
			}
		});
	</script>
</head>
<body class="soria">
	
	<div dojoType="dijit.layout.BorderContainer" design="sidebar" id="main">
		<div id="folders" dojoType="dijit.layout.ContentPane" region="leading" 
			style="width: 200px;padding: 0;" splitter="true">
			<table dojoType="dojox.grid.DataGrid"id="folderGrid"
				store="checkstyleStore" style="height: 100%; width: 100%;"
				query="{ folder: 1 }" rowsPerPage="20" rowSelector="20px"
				onCellClick="onFolderClick(arguments[0])"
				>
				<thead>
					<tr>
						<th field="file" width="auto">Folders</th>
					</tr>
				</thead>
			</table>
		</div>
		<div id="header" dojoType="dijit.layout.ContentPane" region="top" style="height: 50px;">
			<h1>Checkstyle results from <span id="reportDate"></span>
				Total errors:<span id="totalErrors"></span>
			</h1>
		</div>
		<div id="mainTab" dojoType="dijit.layout.TabContainer" region="center" style="padding: 0;">
			<div id="errorsTab" dojoType="dijit.layout.BorderContainer" title="Error List" style="height:100%;width:100%;">
				<table dojoType="dojox.grid.DataGrid" id="messagesGrid"
					class="checkstyleGrid" store="checkstyleStore" 
					query="{ folder: 0 }" rowsPerPage="50" rowSelector="20px"
					region="top"
					style="height:50%;"
					>
					<script type="dojo/connect" event="_onFetchBegin" args="size, req">
						dojo.byId("totalErrors").innerHTML = size;
					</script>
					<thead>
						<tr>
							<th field="file" width="300px">File</th>
							<th field="line" width="40px">Line</th>
							<th field="msg" width="auto" formatter="formatMessage">Message</th>
						</tr>
					</thead>
				</table>
				<div dojoType="dijit.layout.ContentPane" region="bottom" splitter="true" style="height:45%;">
					<div>
						<div dojoType="dijit.form.ToggleButton" 
							 id="showFileErrorsBtn"
							 label="Show File Errors" 
							 iconClass="dijitRadioIcon"
							 onclick="showCurrentErrors()"
							 disabled="true"
							 ></div>
						<div dojoType="dijit.form.ToggleButton" 
							 id="showAllErrorsBtn"
							 label="Show All Errors" 
							 iconClass="dijitRadioIcon"
							 checked="true"
							 onclick="showAllErrors()"></div>
						<div dojoType="dijit.form.Button" 
							 id="makeFixesBtn"
							 label="Make Fixes" 
							 onclick="makeSimpleFixes()"></div>
						<div dojoType="dijit.form.Button" 
							 id="saveFileBtn"
							 label="Save" 
							 onclick="saveFile()"></div>
						<div dojoType="dijit.form.Button" 
							 id="saveAllFileBtn"
							 label="Save All" 
							 onclick="showSaveDialog()"></div>
					</div>
					<div>
						<textarea id="editInput" rows="7" cols="100"></textarea>
					</div>
				</div>
			</div>
			<div id="chartTab" dojoType="dijit.layout.BorderContainer" style="width:100%;height:100%;" title="Worst Modules">
				<div dojoType="dijit.layout.ContentPane" region="top">
					This chart displays the folders of depth 2 in descending order of checkstyle violations.
				</div>
				<div dojoType="dijit.layout.ContentPane" region="center">
					<div id="chart" style="height:400px; width: 1000px;"></div>
				</div>
			</div>
		</div>
	</div>
	<div dojoType="dijit.Dialog" id="changedFilesDlg" title="Save Changed Files">
		<div id="checks">
			
		</div>
		<div dojoType="dijit.form.Button" label="Save" onclick="saveAllChangedFiles()"></div>
		<div dojoType="dijit.form.Button" label="Cancel" onclick="dijit.byId('changedFilesDlg').hide();"></div>
	</div>
</body>
</html>
